{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "A = torch.tensor([1,2,3],dtype=torch.float32)\n",
    "B=torch.tensor([[1,2,3],[-2,-4,-6],[7,8,9]],dtype=torch.float32)\n",
    "A_norm = A / torch.norm(A, dim=0, keepdim=True)\n",
    "B_norm = B / torch.norm(B,dim=1, keepdim=True)\n",
    "cos_similarity = torch.mm(A_norm, B_norm.T)\n",
    "print(cos_similarity)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def l2_normalize(x, dim=None, epsilon=1e-12):\n",
    "    \"\"\"Normalizes a given vector or matrix.\"\"\"\n",
    "    square_sum = torch.sum(x ** 2, dim=dim, keepdim=True)\n",
    "    x_inv_norm = torch.rsqrt(torch.maximum(square_sum, torch.tensor(epsilon, device=x.device)))\n",
    "    return x * x_inv_norm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([0.9487, 0.3162])\n"
     ]
    }
   ],
   "source": [
    "print(l2_normalize(torch.tensor([3,1],dtype=torch.float32)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([3, 2])\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\DELL\\AppData\\Local\\Temp\\ipykernel_21168\\2456825629.py:3: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n",
      "  torch.norm(torch.tensor(x,dtype=torch.float32),dim=1,keepdim=True)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "tensor([[ 5.0000],\n",
       "        [10.0000],\n",
       "        [ 1.4142]])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.tensor([[3,4],[6,8],[1,1]],dtype=torch.float32)\n",
    "print(x.shape)\n",
    "torch.norm(torch.tensor(x,dtype=torch.float32),dim=1,keepdim=True)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "torch_hwzhao",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.16"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
